module DataMiso(
	input							clk,			//80M时钟
	input							rst,
	input							rd_en,
	output	reg				CS,
	output	reg				SPI_SCLK,
	input							SPI_SDI,
	output	reg				SPI_SDO,

	input				[15:0]	CMD,			//命令
	output	reg	[7:0]		STX,			//帧头
	output	reg	[7:0]		XC,			//数据长度
	output	reg	[31:0]	REC_DATA,	//数据
	output	reg	[4:0]		addr_ROM,	//存数地址
	output	reg	[7:0]		VS,			//校验和
	output	reg	[7:0]		ETX			//帧尾
);

reg[4:0]	addr_cnt;
parameter	READY		= 4'd1;
parameter	IDLE		= 4'd2;
parameter	data_CMD	= 4'd3;
parameter	SCLK_L	= 4'd4;
parameter	data_STX	= 4'd5;
parameter	data_XC	= 4'd6;
parameter	data_DATA= 4'd7;
parameter	data_VS	= 4'd8;
parameter	data_ETX	= 4'd9;
parameter	OVER1		= 4'd10;
parameter	OVER		= 4'd11;


reg[3:0]	state;
reg[1:0]	cnt_4;
reg[7:0]	cnt_STX;
reg[7:0]	cnt_CMD;
reg[7:0]	cnt_XC;
reg[7:0]	cnt_data;
reg[7:0]	cnt_VS;
reg[7:0]	cnt_ETX;
reg[7:0]	cnt_OVER1;

reg[7:0]  STX1;
reg[7:0]  XC1;
reg[31:0] DATA;
reg[7:0]  VS1;
reg[7:0]  ETX1;

reg[4:0]cnt_8;
reg[4:0]cnt_5;
reg     ROM_CLK;
reg[7:0]SCLK_LL;

always@(posedge clk or negedge rst)
begin
	if(!rst)
		cnt_8	<= 5'd0;
	else if(cnt_8 == 5'd5)
		cnt_8	<= cnt_8;
	else if(state == IDLE)
		cnt_8	<= cnt_8 + 1'b1;
	else
		cnt_8	<= 5'd0;
end

reg en_0,en_1;
wire en_pos;
wire en_neg;
always@(posedge clk or negedge rst)
begin
	if(!rst)
	begin
		{en_1,en_0} <= 2'b0;
	end
	else
	begin
		{en_1,en_0} <= {en_0,rd_en};
	end
end

assign en_pos = ((~en_1) &(en_0))?1'b1:1'b0;  /* 取上升沿 */
assign en_neg = ((~en_0) &(en_1))?1'b1:1'b0;  /* 取下降沿 */
always@(posedge clk or negedge rst)
begin
	if(!rst)
	begin
		CS			<= 1'b1;
		state		<= READY;
		cnt_5		<= 0;
		STX1		<= 0;
		XC1		<= 0;
		DATA		<= 0;
		VS1		<= 0;
		ETX1		<= 0;
		STX		<= 0;
		XC			<= 0;
		VS			<= 0;
		ETX		<= 0;
		cnt_STX	<= 8'd9;
		cnt_CMD	<= 8'd15;
		cnt_XC	<= 8'd7;
		cnt_data	<= 8'd31;
		cnt_VS	<= 8'd7;
		cnt_ETX	<= 8'd7;
		cnt_OVER1<= 8'd5;
		addr_cnt	<= 5'd0;
		ROM_CLK	<= 0;
		SPI_SDO	<= 0;
		SCLK_LL	<= 0;
	end
	else
	begin
		case(state)
		READY:
			if(en_pos)
			begin
				CS			<= 0;
				state		<= IDLE;
				STX1		<= 0;
				XC1		<= 0;
				DATA		<= 0;
				VS1		<= 0;
				ETX1		<= 0;
				ROM_CLK	<= 0;
				addr_cnt	<= 'd0;
				SPI_SDO	<= 0;
				SCLK_LL	<= 0;
			end
			else
			begin
				CS			<= 1'b1;
				state		<= READY;
				STX1		<= 0;
				XC1		<= 0;
				DATA		<= 0;
				VS1		<= 0;
				ETX1		<= 0;
				ROM_CLK	<= 0;
				SPI_SDO	<= 0;
			end
		IDLE:
			if(cnt_8 == 'd5)
			begin
				state		<= data_CMD;
				cnt_STX  <= 'd9;
				cnt_CMD  <= 'd15;
				cnt_XC   <= 'd7;
				cnt_data <= 'd31;
				cnt_VS   <= 'd7;
				cnt_ETX  <= 'd7;
				cnt_OVER1<= 'd5;
				addr_cnt	<= 'd0;
				ROM_CLK	<= 0;
				SPI_SDO	<= 0;
			end
		data_CMD:
			if(cnt_4 == 'd0)
			begin
				CS	<= 0;
				if(cnt_CMD > 'd0)
				begin
					SPI_SDO	<= CMD[cnt_CMD];
					cnt_CMD	<= cnt_CMD - 'd1;
				end
				else
				begin
					SPI_SDO	<= CMD[0];
					state		<= SCLK_L;
				end
			end
		SCLK_L:
		begin
			if(SCLK_LL > 'd20)
			begin
				SCLK_LL	<= 0;
				state		<= data_STX;
				CS			<= 0;
			end
			else if(SCLK_LL == 'd4)
			begin
				state		<= SCLK_L;
				SCLK_LL	<= SCLK_LL + 1;
				CS			<= 0;
				SPI_SDO	<= 0;
			end
			else
			begin
				CS			<= 0;
				SCLK_LL	<= SCLK_LL + 1;
				state		<= SCLK_L;
			end
		end
		data_STX:
		if(cnt_4 == 'd2)
		begin
			CS	<= 0;
			if(cnt_STX > 'd0)
			begin
				STX1[cnt_STX]	<= SPI_SDI;
				cnt_STX			<= cnt_STX - 'd1;
			end
			else
			begin
				STX1[0]	<= SPI_SDI;
				state		<= data_XC;
			end
		end
		data_XC:
		if(cnt_4 == 'd2)
		begin
			CS	<= 0;
			if(cnt_XC > 'd0)
			begin
				XC1[cnt_XC]	<= SPI_SDI;
				cnt_XC		<= cnt_XC - 'd1;
				STX			<= STX1;
			end
			else
			begin
				XC1[0]	<= SPI_SDI;
				state		<= data_DATA;
			end
		end
		data_DATA:
		if(cnt_4 == 'd2)
		begin
			if(addr_cnt < XC1)
			begin
				CS	<= 0;
				if(cnt_data > 'd0)
				begin
					DATA[cnt_data]	<= SPI_SDI ;
					cnt_data			<= cnt_data - 'd1;
					addr_cnt			<= addr_cnt;
					ROM_CLK			<= 0;
					XC					<= XC1;
				end
				else if(cnt_data == 'd0)
				begin
					DATA[0]	<= SPI_SDI;
					state		<= state;
					addr_cnt	<= addr_cnt + 1;
					cnt_data	<= 'd31;
					ROM_CLK	<= 1;
				end
			end
			else
			begin
				state			<= data_VS;
				VS1[cnt_VS] <= SPI_SDI ;
				cnt_VS		<= cnt_VS - 'd1;
			end
		end
		data_VS:
		if(cnt_4 == 'd2)
		begin
			CS	<= 0;
			if(cnt_VS > 'd0)
			begin
				VS1[cnt_VS]	<= SPI_SDI;
				cnt_VS		<= cnt_VS - 'd1;
			end
			else
			begin
				VS1[0]	<= SPI_SDI;
				state		<= data_ETX;
			end
		end
		data_ETX:
		if(cnt_4 == 'd2)
		begin
			CS	<= 0;
			if(cnt_ETX > 'd0)
			begin
				ETX1[cnt_ETX]	<= SPI_SDI;
				cnt_ETX			<= cnt_ETX - 'd1;
				VS					<= VS1;
			end
			else
			begin
				ETX1[0]	<= SPI_SDI;
				state		<= OVER1;
			end
		end
		OVER1:
		if(cnt_4 == 'd2)
		begin
			CS	<= 0;
			if(cnt_OVER1 > 'd0)
			begin
				ETX		<= ETX1;
				cnt_OVER1<= cnt_OVER1 - 'd1;
			end
			else
			begin
				state	<= OVER;
				CS		<= 0;
			end
		end
		OVER:
		begin
			if(cnt_5 == 'd4)
			begin
				CS		<= 1;
				state	<= READY;
				cnt_5	<= 0;
			end
			else
			begin
				cnt_5	<= cnt_5 + 1;
				CS		<= 0;
				state	<= state;
			end
		end
		default:
		begin
			state		<= READY;
			STX1		<= 0;
			XC1		<= 0;
			VS1		<= 0;
			ETX1		<= 0;
			STX		<= 0;
			XC			<= 0;
			DATA		<= 0;
			VS			<= 0;
			ETX		<= 0;
			ROM_CLK	<= 0;
			CS			<= 1;
			SPI_SDO	<= 0;
		end
		endcase
	end
end

always@(posedge clk or negedge rst)
begin
    if(!rst)
        SPI_SCLK	<= 1'b0;
    else if(cnt_4 == 'd0)
        SPI_SCLK	<= 1'b1;
    else if(cnt_4 == 'd2)
        SPI_SCLK	<= 1'b0;
    else
        SPI_SCLK	<= SPI_SCLK;
end

always@(posedge clk or negedge rst)
begin
	if(!rst)
		cnt_4	<= 'd2;
	else if(state == data_STX )
		cnt_4	<= cnt_4 + 1'b1;
	else if(state == data_CMD )
		cnt_4	<= cnt_4 + 1'b1;
	else if(state == SCLK_L )
		cnt_4	<= 'd2;
	else if(state == data_XC )
		cnt_4	<= cnt_4 + 1'b1;
	else if(state == data_DATA )
		cnt_4	<= cnt_4 + 1'b1;
	else if(state == data_VS)
		cnt_4	<= cnt_4 + 1'b1;
	else if(state == data_ETX )
		cnt_4	<= cnt_4 + 1'b1;
	else if(state == OVER1 )
		cnt_4	<= cnt_4 + 1'b1;
	else
		cnt_4	<= 'd2;
end

always@(posedge clk)
begin
	if(en_pos)
	begin
		REC_DATA	<= 0;
		addr_ROM	<= 0;
	end
	else if(ROM_CLK)
	begin
		REC_DATA	<= DATA;
		addr_ROM	<= addr_cnt;
	end
	else
	begin
		REC_DATA	<= REC_DATA;
		addr_ROM	<= addr_ROM;
	end
end


endmodule
